Skip to content

feat: nip77#464

Open
nogringo wants to merge 3 commits intomasterfrom
feat/nip77
Open

feat: nip77#464
nogringo wants to merge 3 commits intomasterfrom
feat/nip77

Conversation

@nogringo
Copy link
Collaborator

@nogringo nogringo commented Feb 23, 2026

TODO

  • Documentation
  • API to auto fetch / upload missing events

@nogringo nogringo requested review from 1-leo and frnandu February 23, 2026 21:00
@codecov
Copy link

codecov bot commented Feb 23, 2026

Codecov Report

❌ Patch coverage is 71.94444% with 101 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.89%. Comparing base (c2e6102) to head (184ec2d).
⚠️ Report is 93 commits behind head on master.

Files with missing lines Patch % Lines
...ges/ndk/lib/domain_layer/usecases/nip77/nip77.dart 53.09% 53 Missing ⚠️
packages/ndk/lib/shared/nips/nip77/negentropy.dart 84.93% 25 Missing ⚠️
...ges/ndk/lib/domain_layer/entities/nip77_state.dart 64.28% 15 Missing ⚠️
...s/ndk/lib/domain_layer/usecases/relay_manager.dart 79.16% 5 Missing ⚠️
.../lib/shared/decode_nostr_msg/decode_nostr_msg.dart 50.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #464      +/-   ##
==========================================
- Coverage   76.01%   75.89%   -0.13%     
==========================================
  Files         152      155       +3     
  Lines        6204     6563     +359     
==========================================
+ Hits         4716     4981     +265     
- Misses       1488     1582      +94     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.


/// Internal implementation of NIP-77 Negentropy sync
/// This class is not part of the public API
class Nip77Internal {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non descriptive name. Classes can be private with _MyClass "import" possible via part

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or instead of seperating making the methods private?

Copy link
Collaborator

@frnandu frnandu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High-Value Improvements

  • Verify relay origin on incoming NEG messages: processNegMsg / processNegErr trust subscriptionId only; add state.relayUrl == relayUrl check to avoid cross-relay session contamination. (packages/ndk/lib/domain_layer/usecases/nip77/nip77.dart:254, packages/ndk/lib/domain_layer/usecases/nip77/nip77.dart:290)
  • NOTICE fallback detection is brittle: checking only noticeMsg.contains('negentropy') will miss many real-world unsupported-command notices. Consider broader patterns (NEG-OPEN, unsupported, unknown command) or rely primarily on NEG-ERR + capability checks. (packages/ndk/lib/domain_layer/usecases/relay_manager.dart:533)
  • createInitialMessage(..., idSize) has an unused parameter; remove or use it consistently. (packages/ndk/lib/shared/nips/nip77/negentropy.dart:137)
    Tests/Docs Gaps
  • One unit test is effectively a no-op (expect(needIds.length + haveIds.length, greaterThanOrEqualTo(0))). Replace with deterministic multi-round assertions or protocol fixture tests. (packages/ndk/test/nips/nip77_test.dart:266)
  • Integration tests depend on public relays and may be flaky in CI; consider mock transport/in-memory relay tests for reliable protocol behavior. (packages/ndk/test/usecases/nip77/nip77_integration_test.dart:57)
  • Docs have a duplicated section title and likely outdated fallback call (ndk.query(...) may not match current API conventions). (doc/usecases/negentropy.md:5, doc/usecases/negentropy.md:40)

return items;
}

Future<List<neg.NegentropyItem>> _buildItemsFromFilter(Filter filter) async {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filter mismatch in local cache query: Nip77Internal._buildItemsFromFilter only forwards authors/kinds/since/until, but NEG-OPEN sends the full filter.toMap().
This can produce false needIds/haveIds for filters using ids, tags, search, or limit.
Update loadEvents(...) call to pass the full filter surface. (packages/ndk/lib/domain_layer/usecases/nip77/nip77.dart:237)

return Nip77Response(state);
}

Future<void> _startReconciliation({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race on timeout vs async startup: timeout can complete/remove session, but _startReconciliation may continue and still send NEG-OPEN because it never re-checks state.isCompleted after awaits. Add guards before send (and after major awaits). (packages/ndk/lib/domain_layer/usecases/nip77/nip77.dart:139, packages/ndk/lib/domain_layer/usecases/nip77/nip77.dart:159)

int value = 0;
int bytesConsumed = 0;

while (offset + bytesConsumed < data.length) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Varint decode accepts truncated payloads: decodeVarint can exit at end-of-buffer with continuation bit still set and return a partial value instead of throwing. This is a protocol correctness bug for malformed input. (packages/ndk/lib/shared/nips/nip77/negentropy.dart:57)

}
}

void closeAll() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Active NIP-77 sessions are not closed on Ndk.destroy(): no call path to Nip77Internal.closeAll(), so in-flight negotiation streams/futures may linger until timeout. Wire cleanup into lifecycle shutdown. (packages/ndk/lib/presentation_layer/ndk.dart:166, packages/ndk/lib/domain_layer/usecases/nip77/nip77.dart:326)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants